package com.pureut.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pureut.storage.domain.*;
import com.pureut.storage.dto.PickingSchemeDto;
import com.pureut.storage.dto.SchemeDto;
import com.pureut.storage.mapper.*;
import com.pureut.storage.service.PickingSchemeService;
import com.pureut.storage.vo.PickingSchemeRelationVo;
import com.pureut.storage.vo.PickingSchemeVo;
import com.pureut.storage.vo.SchemeVo;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.satoken.utils.LoginHelper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/***
 * 拣货策略实现层
 * Author:C
 * Date:2022/12/21 15:25
 * @DESC
 */
@Service
@RequiredArgsConstructor
public class PickingSchemeServiceImpl implements PickingSchemeService {

    private final PickingSchemeMapper pickingSchemeMapper;
    private final PickingSchemeStrategyMapper pickingSchemeStrategyMapper;
    private final PickingSchemeRelationMapper pickingSchemeRelationMapper;
    private final WmsStockInfoMapper wmsStockInfoMapper;
    private final WarehouseMapper warehouseMapper;

    /**
     * 获取拣货方案列表
     *
     * @param pickingSchemeVo
     * @return
     */
    @Override
    public TableDataInfo<PickingSchemeDto> getList(PickingSchemeVo pickingSchemeVo, PageQuery pageQuery) {
        Page<PickingSchemeDto> pickingSchemeList = pickingSchemeMapper.getPickingSchemeList(pageQuery.build(), pickingSchemeVo);

        return TableDataInfo.build(pickingSchemeList);
    }

    /**
     * 新增
     *
     * @param pickingSchemeVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addPickingScheme(PickingSchemeVo pickingSchemeVo) {
        PickingScheme pickingScheme = new PickingScheme();
        pickingScheme.setDeptId(LoginHelper.getDeptId());
        pickingScheme.setProgrammeCode(pickingSchemeVo.getProgrammeCode());
        pickingScheme.setProgrammeName(pickingSchemeVo.getProgrammeName());
        pickingScheme.setProgrammeView(pickingSchemeVo.getProgrammeView());
        pickingScheme.setDefaultFlag(pickingSchemeVo.getDefaultFlag());
        //查询编码是否唯一
        PickingScheme pickingScheme1 = pickingSchemeMapper.selectOne(new QueryWrapper<PickingScheme>()
            .lambda().eq(PickingScheme::getProgrammeCode, pickingSchemeVo.getProgrammeCode()));
        if (pickingScheme1 != null) {
            throw new GlobalException("该编码已存在");
        }
        //查询有没有默认标志的数据
        PickingScheme one = pickingSchemeMapper.selectOne(new QueryWrapper<PickingScheme>()
            .lambda().eq(PickingScheme::getDefaultFlag, 0));
        if (one != null && pickingScheme.getDefaultFlag() == 0) {
            throw new GlobalException("已经存在默认标志的方案");
        } else {
            pickingSchemeMapper.insert(pickingScheme);
        }
        //存储拣货策略数据
        List<StrategyMessage> strategyMessageList = pickingSchemeVo.getList();

        List<PickingSchemeStrategy> pickingSchemeStrategiesList = new ArrayList<>();
        int num = 1;
        for (StrategyMessage entity : strategyMessageList) {
            PickingSchemeStrategy pickingSchemeStrategy = new PickingSchemeStrategy();
            pickingSchemeStrategy.setPickingId(pickingScheme.getId());
            pickingSchemeStrategy.setStrategyCode(entity.getStrategyCode());
            pickingSchemeStrategy.setStrategyDeliver(entity.getStrategyDeliver());
            pickingSchemeStrategy.setStrategyView(entity.getStrategyView());
            pickingSchemeStrategy.setInspectionSequence(num);
            pickingSchemeStrategy.setStrategyMessageId(entity.getId());
            pickingSchemeStrategy.setEnable(entity.getEnable());
            pickingSchemeStrategiesList.add(pickingSchemeStrategy);
            num++;
        }
        return pickingSchemeStrategyMapper.insertBatch(pickingSchemeStrategiesList);
    }

    /**
     * 修改拣货方案
     *
     * @param pickingSchemeVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePickingScheme(PickingSchemeVo pickingSchemeVo) {
        PickingScheme pickingScheme = pickingSchemeMapper.selectById(pickingSchemeVo.getId());
        if (pickingScheme.getDefaultFlag() == 1) {
            BeanUtils.copyProperties(pickingSchemeVo, pickingScheme);
            pickingSchemeMapper.updateById(pickingScheme);
        } else {
            PickingScheme one = pickingSchemeMapper.selectOne(new QueryWrapper<PickingScheme>().lambda().eq(PickingScheme::getDefaultFlag, 1));
            if (one != null && pickingSchemeVo.getDefaultFlag() == 1) {
                throw new GlobalException("已经存在默认标志的方案");
            } else {
                BeanUtils.copyProperties(pickingSchemeVo, pickingScheme);
                pickingSchemeMapper.updateById(pickingScheme);
            }
        }
        //删除之前存储的拣货策略数据
        List<PickingSchemeStrategy> pickingSchemeStrategies = pickingSchemeStrategyMapper.selectList(new QueryWrapper<PickingSchemeStrategy>().lambda().eq(PickingSchemeStrategy::getPickingId, pickingSchemeVo.getId()));
        boolean b = pickingSchemeStrategyMapper.deleteBatchIds(pickingSchemeStrategies) > 0;
        if (b) {
            List<StrategyMessage> strategyMessageList = pickingSchemeVo.getList();

            List<PickingSchemeStrategy> pickingSchemeStrategiesList = new ArrayList<>();
            int num = 1;
            for (StrategyMessage entity : strategyMessageList) {
                PickingSchemeStrategy pickingSchemeStrategy = new PickingSchemeStrategy();
                pickingSchemeStrategy.setPickingId(pickingScheme.getId());
                pickingSchemeStrategy.setStrategyCode(entity.getStrategyCode());
                pickingSchemeStrategy.setStrategyDeliver(entity.getStrategyDeliver());
                pickingSchemeStrategy.setStrategyView(entity.getStrategyView());
                pickingSchemeStrategy.setInspectionSequence(num);
                pickingSchemeStrategy.setStrategyMessageId(entity.getId());
                pickingSchemeStrategy.setEnable(entity.getEnable());
                pickingSchemeStrategiesList.add(pickingSchemeStrategy);
                num++;
            }
            pickingSchemeStrategyMapper.insertBatch(pickingSchemeStrategiesList);
        }
        return b;
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public PickingSchemeDto getView(Long id) {
        PickingSchemeDto pickingSchemeDto = new PickingSchemeDto();
        PickingScheme pickingScheme = pickingSchemeMapper.selectById(id);
        BeanUtils.copyProperties(pickingScheme, pickingSchemeDto);

        //根据id获取已经选取的策略id
        List<PickingSchemeStrategy> pickingSchemeStrategies = pickingSchemeStrategyMapper.selectList(new QueryWrapper<PickingSchemeStrategy>().lambda().eq(PickingSchemeStrategy::getPickingId, id));

        pickingSchemeDto.setStrategyMessageList(pickingSchemeStrategies);
        return pickingSchemeDto;
    }


    /**
     * 关联
     *
     * @param pickingSchemeRelationVo
     * @return
     */
    @Override
    public boolean relation(PickingSchemeRelationVo pickingSchemeRelationVo) {

        PickingSchemeRelation pickingSchemeRelation = new PickingSchemeRelation();

        //如果是通过仓库关联
        if ("1".equals(pickingSchemeRelationVo.getControlType())) {
            pickingSchemeRelation.setConnectedPerson(LoginHelper.getUsername());
            pickingSchemeRelation.setConnectedTime(new Date());
            pickingSchemeRelation.setControlType(String.valueOf(pickingSchemeRelationVo.getControlType()));
            pickingSchemeRelation.setAssociatedDetails(pickingSchemeRelationVo.getWarehouseDocument());
            pickingSchemeRelation.setControlSign(pickingSchemeRelationVo.getControlSign());
            pickingSchemeRelation.setPickingId(pickingSchemeRelationVo.getId());
        }
        //如果是通过物料关联
        if ("2".equals(pickingSchemeRelationVo.getControlType())) {
            pickingSchemeRelation.setConnectedPerson(LoginHelper.getUsername());
            pickingSchemeRelation.setConnectedTime(new Date());
            pickingSchemeRelation.setControlType(String.valueOf(pickingSchemeRelationVo.getControlType()));
            pickingSchemeRelation.setAssociatedDetails(pickingSchemeRelationVo.getMaterialCode());
            pickingSchemeRelation.setControlSign(pickingSchemeRelationVo.getControlSign());
            pickingSchemeRelation.setPickingId(pickingSchemeRelationVo.getId());
        }

        return pickingSchemeRelationMapper.insert(pickingSchemeRelation) > 0;
    }

    /**
     * 解绑
     *
     * @param id
     * @return
     */
    @Override
    public boolean relieve(Long id) {
        return pickingSchemeRelationMapper.deleteById(id) > 0;
    }

    /**
     * 删除
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePickingScheme(String ids) {
        List<String> idStr = Arrays.asList(ids.split(","));
        if (idStr.size() == 0) {
            throw new GlobalException("请至少选择一条记录");
        }
        //查询是否存在关联信息
        List<PickingSchemeRelation> pickingSchemeRelations = pickingSchemeRelationMapper.selectList(new QueryWrapper<PickingSchemeRelation>().lambda().in(PickingSchemeRelation::getPickingId, idStr));
        //假如没有关联信息，就将数据删除
        if (pickingSchemeRelations.size() == 0) {
            //删除拣货策略信息
            List<PickingSchemeStrategy> pickingSchemeStrategies = pickingSchemeStrategyMapper.selectList(new QueryWrapper<PickingSchemeStrategy>().lambda().in(PickingSchemeStrategy::getPickingId, idStr));
            pickingSchemeStrategyMapper.deleteBatchIds(pickingSchemeStrategies);
            //删除拣货方案
            List<PickingScheme> pickingSchemes = pickingSchemeMapper.selectBatchIds(idStr);
            return pickingSchemeMapper.deleteBatchIds(pickingSchemes) > 0;
        } else {
            throw new GlobalException("请先解绑关联信息");
        }
    }

    /**
     * 根据物料编码、关联信息、默认标志获取仓库-库区-库位-批次号信息
     *
     * @param schemeVo
     * @return
     */
   @Override
   public SchemeDto getSchemeData(SchemeVo schemeVo) {
       SchemeDto schemeDto = new SchemeDto();
       //通过关联明细获取拣货策略
//        List<PickingSchemeRelation> schemeRelationAssociatedDetails = pickingSchemeRelationMapper.selectList(new QueryWrapper<PickingSchemeRelation>().lambda().eq(PickingSchemeRelation::getAssociatedDetails, schemeVo.getAssociatedDetails()));
//        if(schemeRelationAssociatedDetails.size() < 1 ){
//            schemeDto.setCombinationName("");
//            schemeDto.setControlSign(2);
//            return schemeDto;
//        }
       //通过物料编码获取拣货策略
       List<PickingSchemeRelation> schemeRelationMaterial = pickingSchemeRelationMapper.selectList(new QueryWrapper<PickingSchemeRelation>().lambda().eq(PickingSchemeRelation::getAssociatedDetails, schemeVo.getMaterialCode()));
       if (schemeRelationMaterial.size() != 0) {
           //获取拣货策略
           List<PickingSchemeStrategy> pickingSchemeStrategy = pickingSchemeStrategyMapper.selectList(new QueryWrapper<PickingSchemeStrategy>().lambda().eq(PickingSchemeStrategy::getPickingId, schemeRelationMaterial.get(0).getPickingId()).eq(PickingSchemeStrategy::getEnable, 1));

           if (pickingSchemeStrategy.size() == 0) {
               schemeDto.setCombinationName("");
               schemeDto.setControlSign(2);
               return schemeDto;
           }

           PickingSchemeStrategy pickingSchemeStrategy1 = pickingSchemeStrategy.get(0);
           //通过拣货策略获取仓库数据
           WmsStockInfo wmsStockInfo;
           if ("DS01".equals(pickingSchemeStrategy1.getStrategyCode())) {
               List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialCode, schemeVo.getMaterialCode()).orderByAsc(WmsStockInfo::getWsiReveiveTime).eq(WmsStockInfo::getWsiMaterialStatus, 2));
               if (wmsStockInfoList.size() == 0) {
                   schemeDto.setCombinationName("");
                   schemeDto.setControlSign(2);
                   return schemeDto;
               }
               wmsStockInfo = wmsStockInfoList.get(0);
           } else {
               List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialCode, schemeVo.getMaterialCode()).orderByAsc(WmsStockInfo::getWsiProducedDate).eq(WmsStockInfo::getWsiMaterialStatus, 2));
               if (wmsStockInfoList.size() == 0) {
                   schemeDto.setCombinationName("");
                   schemeDto.setControlSign(2);
                   return schemeDto;
               }
               wmsStockInfo = wmsStockInfoList.get(0);
           }
           schemeDto.setBatchNo(wmsStockInfo.getWsiMaterialBatch());
           Warehouse warehouse = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo.getWsiWarehourse()));
           Warehouse warehouse1 = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo.getWsiReservoirArea()));
           Warehouse warehouse2 = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo.getWsiStorageLoaction()));
           String ck = "";
           if (warehouse != null) {
               ck = warehouse.getWarehouseName();
           }
           String kq = "";
           if (warehouse1 != null) {
               kq = warehouse1.getWarehouseName();
           }
           String kw = "";
           if (warehouse2 != null) {
               kw = warehouse2.getWarehouseName();
           }

           schemeDto.setCombinationName(ck + "-" + kq + "-" + kw + "-" + wmsStockInfo.getWsiMaterialBatch());
           schemeDto.setControlSign(schemeRelationMaterial.get(0).getControlSign());
           return schemeDto;
       }
       //通过关联明细获取拣货策略
       List<PickingSchemeRelation> schemeRelationAssociatedDetails = pickingSchemeRelationMapper.selectList(new QueryWrapper<PickingSchemeRelation>().lambda().eq(PickingSchemeRelation::getAssociatedDetails, schemeVo.getAssociatedDetails()));

       if (schemeRelationAssociatedDetails.size() != 0) {
           //获取拣货策略
           List<PickingSchemeStrategy> pickingSchemeStrategy = pickingSchemeStrategyMapper.selectList(new QueryWrapper<PickingSchemeStrategy>().lambda().eq(PickingSchemeStrategy::getPickingId, schemeRelationAssociatedDetails.get(0).getPickingId()).eq(PickingSchemeStrategy::getEnable, 1));
           if (pickingSchemeStrategy.size() == 0) {
               schemeDto.setCombinationName("");
               schemeDto.setControlSign(2);
               return schemeDto;
           }
           PickingSchemeStrategy pickingSchemeStrategy1 = pickingSchemeStrategy.get(0);
           //通过拣货策略获取仓库数据
           WmsStockInfo wmsStockInfo;
           if ("DS01".equals(pickingSchemeStrategy1.getStrategyCode())) {
               List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialCode, schemeVo.getMaterialCode()).orderByAsc(WmsStockInfo::getWsiReveiveTime).orderByAsc(WmsStockInfo::getWsiReveiveTime).eq(WmsStockInfo::getWsiMaterialStatus, 2));
               if (wmsStockInfoList.size() == 0) {
                   schemeDto.setCombinationName("");
                   schemeDto.setControlSign(2);
                   return schemeDto;
               }
               wmsStockInfo = wmsStockInfoList.get(0);
           } else {
               List<WmsStockInfo> wmsStockInfoList = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialCode, schemeVo.getMaterialCode()).orderByAsc(WmsStockInfo::getWsiProducedDate).orderByAsc(WmsStockInfo::getWsiReveiveTime).eq(WmsStockInfo::getWsiMaterialStatus, 2));
               if (wmsStockInfoList.size() == 0) {
                   schemeDto.setCombinationName("");
                   schemeDto.setControlSign(2);
                   return schemeDto;
               }
               wmsStockInfo = wmsStockInfoList.get(0);
           }
           schemeDto.setBatchNo(wmsStockInfo.getWsiMaterialBatch());

           Warehouse warehouse = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo.getWsiWarehourse()));
           Warehouse warehouse1 = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo.getWsiReservoirArea()));
           Warehouse warehouse2 = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo.getWsiStorageLoaction()));
           String ck = "";
           if (warehouse != null) {
               ck = warehouse.getWarehouseName();
           }
           String kq = "";
           if (warehouse1 != null) {
               kq = warehouse1.getWarehouseName();
           }
           String kw = "";
           if (warehouse2 != null) {
               kw = warehouse2.getWarehouseName();
           }

           schemeDto.setCombinationName(ck + "-" + kq + "-" + kw + "-" + wmsStockInfo.getWsiMaterialBatch());

           schemeDto.setControlSign(schemeRelationAssociatedDetails.get(0).getControlSign());
           return schemeDto;
       }
       //获取默认状态下的拣货策略信息
       PickingScheme pickingScheme = pickingSchemeMapper.selectOne(new QueryWrapper<PickingScheme>().lambda().eq(PickingScheme::getDefaultFlag, 0));
       if (pickingScheme == null) {
           return schemeDto;
       }
       List<PickingSchemeStrategy> pickingSchemeStrategies = pickingSchemeStrategyMapper.selectList(new QueryWrapper<PickingSchemeStrategy>().lambda()
           .eq(PickingSchemeStrategy::getPickingId, pickingScheme.getId()).eq(PickingSchemeStrategy::getEnable, 1));

       if (pickingSchemeStrategies.size() == 0) {
           schemeDto.setCombinationName("");
           schemeDto.setControlSign(2);
           return schemeDto;
       }

       PickingSchemeRelation pickingSchemeRelation = pickingSchemeRelationMapper.selectOne(new QueryWrapper<PickingSchemeRelation>().lambda().eq(PickingSchemeRelation::getAssociatedDetails, schemeVo.getAssociatedDetails()));

       PickingSchemeStrategy pickingSchemeStrategy = pickingSchemeStrategies.get(0);

       List<WmsStockInfo> wmsStockInfo;
       if ("DS01".equals(pickingSchemeStrategy.getStrategyCode())) {
           wmsStockInfo = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialCode, schemeVo.getMaterialCode()).orderByAsc(WmsStockInfo::getWsiReveiveTime).eq(WmsStockInfo::getWsiMaterialStatus, 2));
       } else {
           wmsStockInfo = wmsStockInfoMapper.selectList(new QueryWrapper<WmsStockInfo>().lambda().eq(WmsStockInfo::getWsiMaterialCode, schemeVo.getMaterialCode()).orderByAsc(WmsStockInfo::getWsiProducedDate).eq(WmsStockInfo::getWsiMaterialStatus, 2));
       }

       if (wmsStockInfo.size() == 0) {
           schemeDto.setCombinationName("");
           schemeDto.setControlSign(2);
           return schemeDto;
       }

       WmsStockInfo wmsStockInfo1 = wmsStockInfo.get(0);
       schemeDto.setBatchNo(wmsStockInfo1.getWsiMaterialBatch());

       Warehouse warehouse = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo1.getWsiWarehourse()));
       Warehouse warehouse1 = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo1.getWsiReservoirArea()));
       Warehouse warehouse2 = warehouseMapper.selectOne(new QueryWrapper<Warehouse>().lambda().eq(Warehouse::getId, wmsStockInfo1.getWsiStorageLoaction()));

       String ck = "";
       if (warehouse != null) {
           ck = warehouse.getWarehouseName();
       }
       String kq = "";
       if (warehouse1 != null) {
           kq = warehouse1.getWarehouseName();
       }
       String kw = "";
       if (warehouse2 != null) {
           kw = warehouse2.getWarehouseName();
       }

       schemeDto.setCombinationName(ck + "-" + kq + "-" + kw + "-" + wmsStockInfo1.getWsiMaterialBatch());
       if (pickingSchemeRelation != null) {
           schemeDto.setControlSign(pickingSchemeRelation.getControlSign());
       }
       return schemeDto;
   }
}
